window.onload = function(){
    var elementMain = document.getElementById('main');
    var fragment = document.createDocumentFragment();
    var gameStart = false;
    var timer = null;
    var score = 1;
    var number = 0;
    var refresh = 200;
    var column = 35;
    var row = 35;
    var cellWidth = 20;
    var cellBorder = 1;
    var cellPosition = [];
    var foodPosition = [];
    var snakePosition = [];
    var snakeTail = null;
    var direction = {
        left: false,
        up: false,
        right: false,
        down: false
    };

    document.getElementById('fast').addEventListener('click', function () {
        refreshGame(40);
    });

    for (var n = 0; n < row; n++) {
        for (var m = 0; m < column; m++) {
            var x = m + 1;
            var y = n + 1;
            var cell = document.createElement('span');
            cell.style.width = cellWidth - cellBorder * 2 + 'px';
            cell.style.height = cellWidth - cellBorder * 2 + 'px';
            cell.style.top = n * cellWidth + 'px';
            cell.style.left = m * cellWidth + 'px';
            cell.style.position = 'absolute';
            cell.id = getCellId(x, y);
            if (cellBorder) {
                cell.style.border = cellBorder + 'px solid #333';
            }
            fragment.appendChild(cell);
            cellPosition.push({x: x, y: y});
        }
    }

    elementMain.appendChild(fragment);
    elementMain.style.width = cellWidth * column + 'px';
    elementMain.style.height = cellWidth * row + 'px';

    randomSnake();

    randomFood();

    var game = function(){
        if (!gameStart) return false;

        var snakeHead = snakePosition[0];
        var snakeHeadX = snakeHead.x;
        var snakeHeadY = snakeHead.y;

        if (direction.left) {
            snakeHeadX = snakeHeadX - 1;
        } else if (direction.up) {
            snakeHeadY = snakeHeadY - 1;
        } else if (direction.right) {
            snakeHeadX = snakeHeadX + 1;
        } else if (direction.down) {
            snakeHeadY = snakeHeadY + 1;
        } else {
            return false;
        }

        if (snakeHeadX < 1 || snakeHeadY < 1 || snakeHeadX > column || snakeHeadY > row) {
            gameOver('你撞墙上了');
            return false;
        }

        for (p in snakePosition) {
            if (snakePosition[p].x == snakeHeadX && snakePosition[p].y == snakeHeadY) {
                gameOver('你咬死了你记几');
                return false;
            }
        }

        var eat = eatFood(snakeHeadX, snakeHeadY);

        if (!eat) {
            snakeTail = snakePosition.pop();
        }

        snakePosition.unshift({x: snakeHeadX, y: snakeHeadY});

        refreshSnake();

        if (eat) {
            number = number + 1;
            refreshScore();
            randomFood();

            refresh = refresh > 80 ? refresh - 1 : 80;
            refreshGame(refresh);
        }
    }

    timer = setInterval(game, refresh);

    document.onkeydown = function(event){
        if (event.keyCode == 37 && direction.right != true) {
            direction.left  = true;
            direction.up    = false;
            direction.right = false;
            direction.down  = false;
            gameStart = true;
        } else if (event.keyCode == 38 && direction.down != true) {
            direction.left  = false;
            direction.up    = true;
            direction.right = false;
            direction.down  = false;
            gameStart = true;
        } else if (event.keyCode == 39 && direction.left != true) {
            direction.left  = false;
            direction.up    = false;
            direction.right = true;
            direction.down  = false;
            gameStart = true;
        } else if (event.keyCode == 40 && direction.up != true) {
            direction.left  = false;
            direction.up    = false;
            direction.right = false;
            direction.down  = true;
            gameStart = true;
        } else if (event.keyCode == 32) {
            gameStart = !gameStart;
        }
    }

    function refreshScore(){
        document.getElementById('score').innerHTML = number * score;
    }

    function eatFood(x, y){
        for (f in foodPosition) {
            if (foodPosition[f].x == x && foodPosition[f].y == y) {
                return true;
            }
        }
        return false;
    }

    function randomNum(n, m){
        return parseInt(Math.random() * (m - n) + n);
    }

    function getCellId(x, y){
        return 'cell_' + x + '_' + y;
    }

    function randomFood(){
        var cellAllowPosition = [];
        for (n in cellPosition) {
            var allow = true;
            for (m in snakePosition) {
                if (cellPosition[n].x == snakePosition[m].x && cellPosition[n].y == snakePosition[m].y) {
                    allow = false;
                    break;
                }
            }
            if (allow) {
                cellAllowPosition.push({x: cellPosition[n].x, y: cellPosition[n].y});
            }
        }

        var index = randomNum(0, cellAllowPosition.length - 1);
        foodPosition = [];
        foodPosition.push({x: cellAllowPosition[index].x, y: cellAllowPosition[index].y});
        refreshFood();
    }

    function refreshFood(){
        for (i in foodPosition) {
            document.getElementById(getCellId(foodPosition[i].x, foodPosition[i].y)).className = 'food';
        }
    }

    function randomSnake(){
        var x = randomNum(1, column);
        var y = randomNum(1, row);
        snakePosition.push({x: x, y: y});
        refreshSnake();
    }

    function refreshSnake(){
        if (snakeTail) {
            document.getElementById(getCellId(snakeTail.x, snakeTail.y)).className = '';
        }

        for (i in snakePosition) {
            document.getElementById(getCellId(snakePosition[i].x, snakePosition[i].y)).className = 'snake';
        }
    }

    function refreshGame(value){
        refresh = value;
        clearInterval(timer);
        timer = setInterval(game, refresh);
    }

    function gameOver(text){
        clearInterval(timer);
        gameStart = false;
        alert(text);
        window.location.reload();
    }
}